/*
 * Math.h
 *
 *  Created on: Jun 27, 2009
 *      Author: dragon
 */

#ifndef MATEMATICA_H_
#define MATEMATICA_H_

///* This macro adjust the length of a vector to be always
// * positive by inverting the direction (angle plus 180 degrees)
// * if necessary
// */
//#define POS_LEN(length, angle) { if (length < 0) { length *= -1.0 ; angle += M_PI;} }
///* This macro makes sure the angle is between -pi and pi.
// * Caution! The angle is supposed to be within reasonable
// * bounds. If the value is too big this will cause delay!
// */
//#define BOUND_ANGLE(a) {while ((a)>(M_PI)) (a)-=(2*M_PI);while ((a)<(-M_PI)) (a)+=(2*M_PI);}

#include <cmath>
#include <vector>

#include "Coordenada3d.h"
#include "Coordenada2d.h"
#include "VetorPolar.h"

class Matematica
{
	public:
		static const double MY_NAN;
		static const double MY_PI;
		static const double MY_ZERO;
		static const double limitRaio;
	public:
		Matematica();
		virtual ~Matematica();

		static int min (int a, int b) {
		  return !(b<a)?a:b;     // or: return !comp(b,a)?a:b; for version (2)
		}

		static double min (double a, double b){
			 return !(b<a)?a:b;     // or: return !comp(b,a)?a:b; for version (2)
		}

		static int max (int a, int b) {
		  return (a<b)?b:a;     // or: return comp(a,b)?b:a; for version (2)
		}

		static Coordenada3d polarToCartesiano(double dist, double angle1, double angle2);

		/**
		 * \brief distanciaRelativa().
		 *
		 * Esta função recebe a distancia e o angulo de dois objetos em relação a um ponto e retorna a distancia entre estes dois objetos.
		 * A distancia do objeto1 para o objeto2.
		 *
		 * @param distObj1, double
		 *
		 * @param distObj2, double
		 *
		 * @param anguloObj1, double
		 *
		 * @param anguloObj2, double
		 *
		 */
		static double       distanciaRelativa(double distObj1, double distObj2, double anguloObj1, double anguloObj2);

		/**
		 * \brief distancia().
		 *
		 * Esta função recebe a Coordenada XY de dois objetos e retorna a distancia entre estes dois objetos.
		 * A distancia do objeto1 para o
	VetorPolar v2(distObj2, anguloObj2);objeto2.
		 *
		 * @param obj1, Coordenada2d
		 *
		 * @param obj2, Coordenada2d
		 *
		 */
		static double       distancia(Coordenada2d obj1, Coordenada2d obj2);

		/**
		 * \brief alturaRelativa().
		 *
		 * Esta função recebe a distancia e o angulo vertical de um objeto
		 * e calcula a altura relativa deste objeto para o observador.
		 *
		 * @param distObj, double
		 *
		 * @param angVertObj, double
		 *
		 */
		static double       alturaRelativa(double distObj, double angVertObj);

		/**
		 * \brief anguloCos().
		 *
		 * Esta função recebe o valor do cosseno
		 * e calcula o angulo em graus relativo a este valor.
		 *
		 * @param cosseno, double
		 *
		 */
		static double       anguloCos(double cosseno);

		/**
		 * \brief coeficienteAngular().
		 *
		 * Esta função recebe dois pontos
		 * e calcula o coeficiente angular da reta formada por eles.
		 *
		 * @param ponto1, Coordenada2d
		 * @param ponto2, Coordenada2d
		 *
		 */
		static double       coeficienteAngular(Coordenada2d ponto1, Coordenada2d ponto2);

		static double		normaVetor(Coordenada2d vetor);
		static double		calcAngRotacao(Coordenada2d vetor1, Coordenada2d vetor2);
		static Coordenada2d coordenada2dObjetos(Coordenada2d ponto, double distanciaPontoObjeto,
												double anguloPontoPlano, double anguloPontoObjeto);
		static Coordenada2d coordenada2dRelativa(double distanciaPontoObjeto, double anguloPontoObjeto);

		static VetorPolar   somaVetor(VetorPolar v1, VetorPolar v2);
		static VetorPolar   subtracaoVetor(VetorPolar v1, VetorPolar v2);

		static double       grau2Rad(double angulo);
		static double       rad2Grau(double angulo);
		static double 		calcularRotacao(Coordenada2d v1,Coordenada2d v2);

		static int          sinal(double valor);
		static int          sinal(int valor);

		static double		signum(double x);

		static double       myfabs(double valor);
		static int       	myfabs(int valor);

		static int			binary_search(std::vector<double> arr, double find);
		static bool			isWithinArea(Coordenada2d point1,Coordenada2d point2);

	private:
		static VetorPolar   ajusteComprimento(VetorPolar vetor);
		static double		limitandoAngulo(double angulo);

};

#endif /* MATEMATICA_H_ */
